package main

import (
	"encoding/csv"
	"fmt"
	"log"
	"os"
	"regexp"
	"strconv"
	"strings"
)

type Region struct {
	Full        string
	Short       string
	Pinyin      string
	Node        string
	ParentIndex string
	Parent      *Region
}

func HasNumeric(word string) bool {
	numeric := regexp.MustCompile(`\d`).MatchString(word)
	return numeric
}

var parentNode = make(map[string]Region)

func main() {
	data, err := read("./data/district-full.csv")
	if err != nil {
		panic(err)
	}

	result := make([]Region, 0)
	for _, item := range data {
		parts := strings.Fields(item[0])
		suffix := ""
		log.Printf("item %+v %+v", len(parts), parts)
		if len(parts) <= 7 {
			continue
		}
		if !HasNumeric(parts[6]) {
			suffix += parts[6]
		}
		if !HasNumeric(parts[7]) {
			suffix += parts[7]
		}
		region := Region{
			Full:        parts[1] + suffix,
			Short:       parts[1],
			Pinyin:      parts[5],
			Node:        parts[0],
			ParentIndex: parts[2],
		}

		addNode(region, parentNode)
		parent := findParentNode(region, parentNode)
		region.Parent = parent

		result = append(result, region)

	}

	write(result)
}

func write(regions []Region) {
	data, err := read("data/region_en.csv")
	if err != nil {
		panic(err)
	}

	result := make([][]string, 0)
	result = append(result, data...)

	for _, region := range regions {
		if region.Parent == nil {
			continue
		}
		found := false
		for _, item := range data {
			if region.Short == item[0] {
				found = true
			}
		}
		if found {
			continue
		}
		result = append(result, []string{
			region.Short,
			region.Full,
			region.Pinyin,
			region.Parent.Short,
			region.Parent.Pinyin,
			"South",
			"Tier 3",
		})
	}
	output := ""
	for _, item := range result {
		if len(item) != 7 {
			panic(fmt.Errorf("err"))
		}
		output += strings.Join(item, ",") + "\n"
	}
	err = os.WriteFile("./data/district_test.csv", []byte(output), 0766)
	if err != nil {
		panic(err)
	}
}

func addNode(region Region, parentNode map[string]Region) {
	parentNode[region.Node] = region
}

func findParentNode(region Region, parentNode map[string]Region) *Region {
	if parent, ok := parentNode[region.ParentIndex]; ok {
		nodeInt, _ := strconv.ParseInt(parent.Node, 10, 64)
		if nodeInt <= 34 {
			return &parent
		}
		r := parentNode[parentNode[region.ParentIndex].ParentIndex]
		return &r
	}
	return nil
}

func read(p string) ([][]string, error) {
	f, err := os.OpenFile(p, os.O_RDONLY, 0666)
	if err != nil {
		return nil, err
	}
	data, err := csv.NewReader(f).ReadAll()
	if err != nil {
		return nil, err
	}
	return data, nil
}
